package BeanUtils

import (
	"errors"
	"reflect"
)

func ReCopyProperties(source, dist any, handle ...Handler) (interface{}, error) {
	sourceVal, distVal := reflect.Indirect(reflect.ValueOf(source)), reflect.Indirect(reflect.ValueOf(dist))
	if sourceVal.Kind() != reflect.Slice {
		return nil, errors.New("source type error")
	}
	result := makeSlice(distVal.Type(), sourceVal.Len())
	if err := circCopy(sourceVal, result, distVal.Type(), handle...); err != nil {
		return nil, err
	}
	return result.Interface(), nil
}

func circCopy(source, result reflect.Value, disT reflect.Type, handle ...Handler) error {
	for i := 0; i < source.Len(); i++ {
		element := source.Index(i)
		dist := reflect.New(getElementType(disT))
		if dist.IsValid() || dist.IsNil() {
			if source.Index(i).Kind() == reflect.Ptr {
				element = source.Index(i).Elem()
			}
			copyProperty(element.Interface(), dist.Interface())
			if len(handle) == 1 {
				handle[0](source, dist)
			}
			result.Index(i).Set(dist)
		}
	}
	return nil
}
